#ifndef LIVERECORDERTYPE_H
#define LIVERECORDERTYPE_H

#include "globaltype.h"
#include <functional>
#include <QObject>
#include <QPointer>

enum LiveDataRole {
    LIVE_STATUS_ROLE = OTHER_ROLE,
    AUDIENCE_COUNT_ROLE,
    RECORD_STATUS_ROLE,
    MESSAGE_ROLE,
    AUTO_CHECK_ROLE,
    AUTO_RECORD_ROLE,
    RECORD_DURATION_ROLE,
    LOADING_INDEX_ROLE
};

enum RecordStatus { RECORDING_STATUS = 1, MERGEING_STATUS };

using LiveFunctor = std::function<void(int, const QString&)>;

template<class T>
struct LiveFunctionTrait
{
    using F = void (T::*)(int, const QString&);
};

class LiveHandler
{
public:
    LiveHandler() { }

    template<class T>
    LiveHandler(T* obj, typename LiveFunctionTrait<T>::F f)
        : is_qo_f_(true), obj_(obj), obj_used_(obj != nullptr)
    {
        f_ = std::bind(f, obj, std::placeholders::_1, std::placeholders::_2);
    }
    template<class T>
    explicit LiveHandler(T* obj, const LiveFunctor& f)
        : is_qo_f_(false), obj_(obj), obj_used_(obj != nullptr), f_(f)
    {
    }
    explicit LiveHandler(const LiveFunctor& f) : is_qo_f_(false), obj_used_(false), f_(f) { }

    LiveHandler(const LiveHandler& other)
        : is_qo_f_(other.is_qo_f_), obj_(other.obj_), obj_used_(other.obj_used_), f_(other.f_)
    {
    }

    LiveHandler& operator=(const LiveHandler& other)
    {
        if (this != &other) {
            is_qo_f_ = other.is_qo_f_;
            obj_ = other.obj_;
            obj_used_ = other.obj_used_;
            f_ = other.f_;
        }
        return *this;
    }

    operator bool() const
    {
        if (obj_used_ && obj_.isNull())
            return false;
        return (!is_qo_f_ && f_) || (is_qo_f_ && obj_);
    }
    void operator()(int presenter, const QString& args) const
    {
        if (obj_used_ && obj_.isNull()) {
            return;
        }
        if ((!is_qo_f_ && f_) || (is_qo_f_ && obj_)) {
            f_(presenter, args);
        }
    }

private:
    bool is_qo_f_;
    QPointer<QObject> obj_;
    bool obj_used_;
    LiveFunctor f_;
};

#endif // LIVERECORDERTYPE_H
